package com.harmontronics.hanma.paas.paas.domain.app.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.harmontronics.hanma.paas.paas.common.PageBase;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HmEntityModel;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HmPublishedEntityModel;
import com.harmontronics.hanma.paas.paas.domain.app.repository.persistence.HmEntityModelRepository;
import com.harmontronics.hanma.paas.paas.domain.app.repository.persistence.HmModelPublishRepository;
import com.harmontronics.hanma.paas.paas.domain.app.repository.persistence.HmPublishedEntityModelRepository;
import com.harmontronics.hanma.paas.paas.domain.app.repository.po.HmEntityModelPO;
import com.harmontronics.hanma.paas.paas.domain.app.repository.po.HmModelPublishPO;
import com.harmontronics.hanma.paas.paas.domain.app.repository.po.HmPublishedEntityModelPO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("hmPublishedEntityModelService")
@DS("#header.App-Unique")
public class HmPublishedEntityModelService {

    @Autowired
    private HmPublishedEntityModelRepository hmPublishedEntityModelRepository;

    @Autowired
    private HmEntityModelRepository hmEntityModelRepository;

    @Autowired
    private HmModelPublishRepository hmModelPublishRepository;

    public HmPublishedEntityModel findById(Long id) {
        HmPublishedEntityModelPO po = hmPublishedEntityModelRepository.getById(id);
        return BeanUtil.toBean(po, HmPublishedEntityModel.class);
    }

    public void save(HmPublishedEntityModel hmPublishedEntityModel) {
        HmPublishedEntityModelPO po = BeanUtil.toBean(hmPublishedEntityModel, HmPublishedEntityModelPO.class);
        hmPublishedEntityModelRepository.save(po);
    }

    public void update(HmPublishedEntityModel hmPublishedEntityModel) {
        HmPublishedEntityModelPO po = BeanUtil.toBean(hmPublishedEntityModel, HmPublishedEntityModelPO.class);
        hmPublishedEntityModelRepository.updateById(po);
    }

    public void remove(List<Long> ids) {
        hmPublishedEntityModelRepository.removeByIds(ids);
    }

    public List<HmEntityModel> getList(Long publishId) {
        List<HmPublishedEntityModelPO> pos = hmPublishedEntityModelRepository.findByPublishId(publishId);
        List<Long> entityModelIds = pos.stream().map(HmPublishedEntityModelPO::getEntityModelId).collect(Collectors.toList());
        List<HmEntityModelPO> entityModelPOS = hmEntityModelRepository.listByIds(entityModelIds);
        return Convert.toList(HmEntityModel.class, entityModelPOS);
    }


    public List<HmEntityModel> getListByModelId(Long modelId) {
        HmModelPublishPO publishPO = hmModelPublishRepository.findActivatedByModelId(modelId);
        if(publishPO == null){
            return new ArrayList<>();
        }
        return getList(publishPO.getId());
    }

    public PageBase<HmEntityModel> getList(Long modelId,Long publishId,boolean hiddenSystemField, int pageNo, int pageSize) {
        Page<HmPublishedEntityModelPO> page = new Page<>(pageNo, pageSize);
        IPage<HmEntityModel> iPage = hmPublishedEntityModelRepository.findByPublishId(hiddenSystemField,modelId,publishId, page);
        PageBase<HmEntityModel> pageBase = PageBase.from(iPage, HmEntityModel.class);
        return pageBase;
    }


    public void up(Long id) {
        move(id, true);
    }

    public void down(Long id) {
        move(id, false);
    }

    private void move(Long id, boolean up) {
        HmPublishedEntityModelPO publishedEntityModelPO = hmPublishedEntityModelRepository.getById(id);

        int moveNum =
                up
                        ? publishedEntityModelPO.getSerialNum() - 1
                        : publishedEntityModelPO.getSerialNum() + 1;
        publishedEntityModelPO.setSerialNum(moveNum);

        List<HmPublishedEntityModelPO> moveList = new ArrayList<>(2);
        moveList.add(publishedEntityModelPO);

        List<HmPublishedEntityModelPO> hmEntityModelList = hmPublishedEntityModelRepository.findByPublishId(publishedEntityModelPO.getPublishId());
        // 移动节点
        Map<Integer, HmPublishedEntityModelPO> hmEntityModelMap =
                hmEntityModelList.stream()
                        .collect(Collectors
                                .toMap(HmPublishedEntityModelPO::getSerialNum, Function.identity()));

        HmPublishedEntityModelPO moveHmEntityModel = hmEntityModelMap.get(moveNum);
        if (moveHmEntityModel != null) {
            if (up) {
                moveHmEntityModel.setSerialNum(moveNum + 1);
            } else {
                moveHmEntityModel.setSerialNum(moveNum - 1);
            }
            moveList.add(moveHmEntityModel);
        }
        hmPublishedEntityModelRepository.updateBatchById(moveList);
    }

}